package pe.com.bbva.ge.vista.vaadin.ui;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import pe.com.bbva.ge.domain.configuracion.Lista;
import pe.com.bbva.ge.domain.configuracion.Regla;
import pe.com.bbva.ge.domain.configuracion.Valor;
import pe.com.bbva.ge.negocio.ConfiguracionNegocio;
import pe.com.bbva.ge.utileria.Constante;
import pe.com.bbva.ge.utileria.drools.MotorDrools;
import pe.com.bbva.ge.vista.vaadin.ui.component.ComboBoxValor;
import pe.com.bbva.ge.vista.vaadin.ui.utileria.AlertDialog;

//import pe.com.bbva.harec.exception.ValidacionException;
//import pe.com.bbva.harec.model.BitacoraRegla;
//import pe.com.bbva.harec.model.Opcion;
//import pe.com.bbva.harec.model.Regla;
//import pe.com.bbva.harec.model.ReglaDerivacion;
//import pe.com.bbva.harec.model.ReglaTransicion;
//import pe.com.bbva.harec.model.Valor;
//import pe.com.bbva.harec.service.BitacoraReglaService;
//import pe.com.bbva.harec.service.ReglaDerivacionService;
//import pe.com.bbva.harec.service.ReglaService;
//import pe.com.bbva.harec.service.ReglaTransicionService;
//import pe.com.bbva.harec.service.ValorService;
//import pe.com.bbva.harec.util.Constante;
//import pe.com.bbva.harec.vaadin.util.HarecComponent;
//import pe.com.bbva.harec.vaadin.util.Injector;
//import pe.com.bbva.harec.vaadin.util.ValidateLimit;













import com.cdainfo.vaadin.TablaFiltro;
import com.cdainfo.vaadin.container.CDAIndexedContainer;
import com.cdainfo.vaadin.event.TablaFiltroEnterEvent;
import com.cdainfo.vaadin.listener.TablaFiltroEnterListener;
import com.vaadin.data.Item;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.event.FieldEvents.TextChangeEvent;
import com.vaadin.event.FieldEvents.TextChangeListener;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.terminal.Sizeable;
import com.vaadin.ui.AbstractSelect.ItemDescriptionGenerator;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Table.ColumnResizeEvent;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

public class ReglaUI extends VentanaUI implements ClickListener, TablaFiltroEnterListener {
	
	private VerticalLayout vlyRaiz;
	private HorizontalLayout hlyContenido;
	private VerticalLayout vlyListaReglas;
	private HorizontalLayout hlyFiltrosRegla;
	private TablaFiltro tblReglas;
	private VerticalLayout vlyFormularioRegla;
	private Label lblFormularioReglaTitulo;
	private HorizontalLayout hlyFormularioReglaFila1;
	private HorizontalLayout hlyFormularioReglaFila2;
	private HorizontalLayout hlyFormularioReglaFila3;
	private HorizontalLayout hlyFormularioReglaFila5;
	private TextField txtIdRegla;
	private TextField txtCodigoRegla;	
	private TextField txtNombreRegla;
	private TextArea txtContenidoRegla;
	private Button btnGrabarRegla;
	private Button btnEliminarRegla;
	private ComboBoxValor cmbTipoRegla;
	private ComboBoxValor cmbEstado;
	private CDAIndexedContainer container;	
	private static final long serialVersionUID = 1L;
	private boolean flagNuevaRegla;
	
	public static final String NOMBRE		="nombre";
	public static final String CODIGO		="codigo";
	public static final String TIPO_REGLA	="tipoRegla";
	public static final String ESTADO		="estado.nombre";
	
	@Autowired
	private ConfiguracionNegocio genericoNegocio;
	@Autowired
	private MotorDrools motorDrools;
	Window modalEliminar;
	public ReglaUI(){		
		construirVlyRaiz();
		setCompositionRoot(vlyRaiz);
	}
	
	private void debugId(){
		vlyRaiz.setDebugId("mainLayout");
		hlyContenido.setDebugId("pnlReglaContenido");
		vlyFormularioRegla.setDebugId("pnlGrabarRegla");
		hlyFormularioReglaFila5.setDebugId("pnlReglaFila5");
		btnEliminarRegla.setDebugId("btnEliminarRegla");
		btnGrabarRegla.setDebugId("btnGrabarRegla");
		hlyFormularioReglaFila3.setDebugId("pnlReglaFila3");
		txtContenidoRegla.setDebugId("txtContenido");
		hlyFormularioReglaFila2.setDebugId("pnlReglaFila2");
		txtNombreRegla.setDebugId("txtNombreRegla");
		hlyFormularioReglaFila1.setDebugId("pnlReglaFila1");		
		txtCodigoRegla.setDebugId("txtCodigoRegla");
		txtIdRegla.setDebugId("lblIdRegla");
		lblFormularioReglaTitulo.setDebugId("lblGrabarRegla");
		vlyListaReglas.setDebugId("pnlReglas");
		tblReglas.setDebugId("tblReglas");
		hlyFiltrosRegla.setDebugId("pnlFiltroReglas");
	}

	public void postConstruccion() {
		debugId();
		List<Regla> reglas = genericoNegocio.obtenerTodos(Regla.class);
		cargarReglas(reglas);
		habilitarFuncionalidadComponentes();
		tblReglas.addListener((TablaFiltroEnterListener)this);
	}
	
	private void habilitarFuncionalidadComponentes(){		
		habilitarEdicion("regla",false);		
		tblReglas.setSelectable(true);
		tblReglas.setImmediate(true);
		agregarListenerTabla();	
		
		btnGrabarRegla.addListener((ClickListener)this);
		btnEliminarRegla.addListener((ClickListener)this);
	}
	
	private void agregarListenerTabla(){
		tblReglas.setItemDescriptionGenerator(new ItemDescriptionGenerator() {
			private static final long serialVersionUID = 1L;
			@Override
			public String generateDescription(Component source, Object itemId,Object propertyId) {
				Item item = tblReglas.getItem(itemId);
				String comentarioAnterior = item.getItemProperty("regla").getValue().toString();
				return comentarioAnterior;
			}
		});
		
		tblReglas.addListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;
			@Override
			public void valueChange(ValueChangeEvent event) {
				boolean esModoNuevo = tblReglas.getValue() == null;
				if (esModoNuevo) {
					tblReglas.setValue(null);
					habilitarEdicion("regla", !esModoNuevo);
					txtIdRegla.setValue("");
					limpiar("regla");
				} else {
					Item item = tblReglas.getItem(tblReglas.getValue());
					txtIdRegla.setValue(item.getItemProperty("id").getValue());
					txtCodigoRegla.setValue(item.getItemProperty("codigo").getValue());
					txtNombreRegla.setValue(item.getItemProperty("nombre").getValue());
					txtContenidoRegla.setValue(item.getItemProperty("regla").getValue());
					cmbTipoRegla.setValue(item.getItemProperty("tipoValorRegla").getValue());
					cmbEstado.setValue(item.getItemProperty("estado").getValue());
					
					habilitarEdicion("regla", !esModoNuevo);
				}
			}
		});
	}
	
	private void habilitarEdicion(String nombre, boolean flag) {
		if (nombre.equals("regla")) {
			flagNuevaRegla = !flag;
			btnEliminarRegla.setVisible(flag);
			if (flag) {
				btnGrabarRegla.setCaption("Actualizar");
			} else {
				btnGrabarRegla.setCaption("Crear");
			}
		}
	}
	
	
	private void cargarReglas(List<Regla> reglas){
		if(container!=null){
			container.removeAllItems();
		}else{
			container = new CDAIndexedContainer();
			container.addContainerProperty("id", String.class, null);
			container.addContainerProperty("codigo", String.class,  null, "Código", CDAIndexedContainer.TipoComponente.TEXT, true, 60);
			container.addContainerProperty("nombre", String.class,  null, "Nombre", CDAIndexedContainer.TipoComponente.TEXT, true, 180);		
			container.addContainerProperty("tipoRegla", String.class,  null, "Tipo",CDAIndexedContainer.TipoComponente.TEXT,true,120);
			container.addContainerProperty("estado.nombre", String.class, null, "Estado",CDAIndexedContainer.TipoComponente.TEXT, true, 40);
			container.addContainerProperty("estado", Valor.class, null);
			container.addContainerProperty("regla", String.class,  null);
			container.addContainerProperty("tipoValorRegla", Valor.class, null);			
			tblReglas.setContainerDataSource(container);
		}
		
		int con=1;
		for (Regla regla : reglas) {
			Item item = container.addItem(con++);
			item.getItemProperty("id").setValue(regla.getId());
            item.getItemProperty("codigo").setValue(regla.getCodigo());
            item.getItemProperty("nombre").setValue(regla.getNombre());
            item.getItemProperty("regla").setValue(regla.getRegla());
            item.getItemProperty("tipoRegla").setValue(regla.getTipo().getNombre());
            item.getItemProperty("tipoValorRegla").setValue(regla.getTipo());
            item.getItemProperty("estado").setValue(regla.getEstado());
            item.getItemProperty("estado.nombre").setValue(regla.getEstado().getNombre());
		}
		
	}
	
	@Override
	public void buttonClick(ClickEvent event) {
		if(event.getButton().equals(btnGrabarRegla)){
			buttonClickGrabarRegla();
		}
		if(event.getButton().equals(btnEliminarRegla)){
			buttonClickEliminarRegla();
		}
	}

	private void buttonClickGrabarRegla(){
		Regla regla = new Regla();
		regla.setCodigo(txtCodigoRegla.getValue().toString().trim());
		regla.setNombre(txtNombreRegla.getValue().toString().trim());
		regla.setRegla(txtContenidoRegla.getValue().toString().trim());
		regla.setTipo((Valor)cmbTipoRegla.getValue());
		regla.setEstado((Valor)cmbEstado.getValue());

		if(!motorDrools.validarRegla(regla)){
			AlertDialog alerta = new AlertDialog("Alerta", "Regla no válida", "Aceptar", "250");
    		getApplication().getMainWindow().getWindow().addWindow(alerta);
		}
		if(flagNuevaRegla){
			genericoNegocio.crear(regla);
		}else{
			regla.setId(Long.parseLong(txtIdRegla.getValue().toString()));
			genericoNegocio.modificar(regla);
		}
		refrescar("regla");
		motorDrools.cargarReglas();
	}
	
	private void buttonClickEliminarRegla(){
		Regla regla = new Regla();
		regla.setId(Long.parseLong(txtIdRegla.getValue().toString()));		
		if(regla !=null){
			modalEliminar(regla);
		}
		refrescar("regla");
	}
	
	public void modalEliminar(Regla regla){		
		modalEliminar=new Window("Eliminar");
		ConfirmacionEliminarUI confirmacionEliminarUI=new ConfirmacionEliminarUI(this,regla,"regla");
		modalEliminar.setContent(confirmacionEliminarUI);
		modalEliminar.center();
		modalEliminar.setModal(true);
		modalEliminar.setDraggable(false);
		modalEliminar.setClosable(true);
		modalEliminar.setResizable(false);
		modalEliminar.setCloseShortcut(KeyCode.ESCAPE, null);
		getApplication().getMainWindow().addWindow(modalEliminar);
	}
	
	public void refrescar(String nombre)	{
		habilitarEdicion(nombre,false);
		limpiar(nombre);
		if(nombre.equals("regla")){
			List<Regla> reglas = genericoNegocio.buscarReglas(null);
			cargarReglas(reglas);
		}
	}
	
	private void limpiar(String nombre)	{
		if(nombre.equals("regla")){
			txtIdRegla.setValue("");
			txtCodigoRegla.setValue("");
			txtNombreRegla.setValue("");
			txtContenidoRegla.setValue("");
			cmbTipoRegla.setValue(null);
			cmbEstado.setValue(null);
		}
	}

	private VerticalLayout construirVlyRaiz() {
		vlyRaiz = new VerticalLayout();
		vlyRaiz.setImmediate(false);
		vlyRaiz.setMargin(false);
		hlyContenido = construirHlyContenido();
		vlyRaiz.addComponent(hlyContenido);		
		return vlyRaiz;
	}
	private HorizontalLayout construirHlyContenido() {
		hlyContenido = new HorizontalLayout();
		hlyContenido.setImmediate(false);
		hlyContenido.setMargin(false);
		hlyContenido.setSpacing(true);
		vlyListaReglas = construirVlyListaReglas();
		hlyContenido.addComponent(vlyListaReglas);
		vlyFormularioRegla = construirVlyFormularioRegla();
		hlyContenido.addComponent(vlyFormularioRegla);		
		return hlyContenido;
	}
	private VerticalLayout construirVlyListaReglas() {
		vlyListaReglas = new VerticalLayout();
		vlyListaReglas.setImmediate(false);
		vlyListaReglas.setMargin(false);
		hlyFiltrosRegla = construirHlyFiltrosRegla();
		vlyListaReglas.addComponent(hlyFiltrosRegla);
		tblReglas = new TablaFiltro();
		tblReglas.setImmediate(false);
		tblReglas.setWidth("100%");
		vlyListaReglas.addComponent(tblReglas);
		return vlyListaReglas;
	}
	private HorizontalLayout construirHlyFiltrosRegla() {
		hlyFiltrosRegla = new HorizontalLayout();
		hlyFiltrosRegla.setImmediate(false);
		hlyFiltrosRegla.setMargin(false);
		return hlyFiltrosRegla;
	}
	private VerticalLayout construirVlyFormularioRegla() {
		vlyFormularioRegla = new VerticalLayout();
		vlyFormularioRegla.setImmediate(false);
		vlyFormularioRegla.setMargin(false);
		vlyFormularioRegla.setSpacing(true);		
		lblFormularioReglaTitulo = new Label();
		lblFormularioReglaTitulo.setImmediate(false);
		lblFormularioReglaTitulo.setValue("Reglas");
		vlyFormularioRegla.addComponent(lblFormularioReglaTitulo);
		hlyFormularioReglaFila1 = construirHlyFormularioReglaFila1();
		vlyFormularioRegla.addComponent(hlyFormularioReglaFila1);
		hlyFormularioReglaFila2 = construirHlyFormularioReglaFila2();
		vlyFormularioRegla.addComponent(hlyFormularioReglaFila2);
		hlyFormularioReglaFila3 = construirHlyFormularioReglaFila3();
		vlyFormularioRegla.addComponent(hlyFormularioReglaFila3);
		
		hlyFormularioReglaFila5 = construirHlyFormularioReglaFila5();
		vlyFormularioRegla.addComponent(hlyFormularioReglaFila5);
		return vlyFormularioRegla;
	}
	private HorizontalLayout construirHlyFormularioReglaFila1() {
		hlyFormularioReglaFila1 = new HorizontalLayout();
		hlyFormularioReglaFila1.setImmediate(false);
		hlyFormularioReglaFila1.setMargin(false);
		hlyFormularioReglaFila1.setSpacing(true);
		
		txtIdRegla = new TextField();
		txtIdRegla.setInputPrompt("Id");
		txtIdRegla.setEnabled(false);
		txtIdRegla.setImmediate(false);
		txtIdRegla.setVisible(false);
		txtIdRegla.setWidth("40px");
		
		txtCodigoRegla = new TextField();
		txtCodigoRegla.setStyleName("fieldRequired");
		txtCodigoRegla.setImmediate(false);
		txtCodigoRegla.setWidth("65px");
		txtCodigoRegla.setInputPrompt("Código");
		
		cmbTipoRegla=new ComboBoxValor(Lista.CODIGO.TIPO_REGLA);
		cmbTipoRegla.setImmediate(true);
		cmbTipoRegla.setWidth("130px");
		cmbTipoRegla.setInputPrompt("Tipo regla");
		cmbTipoRegla.setStyleName("fieldRequired");
		
		cmbEstado=new ComboBoxValor(Constante.LISTA.CODIGO.REGISTRO_ESTADO);
		cmbEstado.setImmediate(true);
		cmbEstado.setWidth("120px");
		cmbEstado.setInputPrompt("Estado");
		cmbEstado.setStyleName("fieldRequired");
		
		hlyFormularioReglaFila1.addComponent(txtCodigoRegla);
		hlyFormularioReglaFila1.addComponent(cmbTipoRegla);
		hlyFormularioReglaFila1.addComponent(cmbEstado);
		hlyFormularioReglaFila1.addComponent(txtIdRegla);
		return hlyFormularioReglaFila1;
	}
	private HorizontalLayout construirHlyFormularioReglaFila2() {
		hlyFormularioReglaFila2 = new HorizontalLayout();
		hlyFormularioReglaFila2.setImmediate(false);
		hlyFormularioReglaFila2.setMargin(false);
		hlyFormularioReglaFila2.setSpacing(true);
		txtNombreRegla = new TextField();
		txtNombreRegla.setStyleName("fieldRequired");
		txtNombreRegla.setImmediate(false);
		txtNombreRegla.setWidth("330px");
		txtNombreRegla.setInputPrompt("Nombre");
		hlyFormularioReglaFila2.addComponent(txtNombreRegla);
		return hlyFormularioReglaFila2;
	}
	private HorizontalLayout construirHlyFormularioReglaFila3() {
		hlyFormularioReglaFila3 = new HorizontalLayout();
		hlyFormularioReglaFila3.setImmediate(false);
		hlyFormularioReglaFila3.setMargin(false);
		hlyFormularioReglaFila3.setSpacing(true);
		txtContenidoRegla = new TextArea();
		txtContenidoRegla.setStyleName("fieldRequired");
		txtContenidoRegla.setImmediate(false);
		txtContenidoRegla.setWidth("330px");
		txtContenidoRegla.setHeight("180px");
		txtContenidoRegla.setInputPrompt("Contenido");
		hlyFormularioReglaFila3.addComponent(txtContenidoRegla);
		return hlyFormularioReglaFila3;
	}
	
	private HorizontalLayout construirHlyFormularioReglaFila5() {
		hlyFormularioReglaFila5 = new HorizontalLayout();
		hlyFormularioReglaFila5.setImmediate(false);
		hlyFormularioReglaFila5.setMargin(false);
		hlyFormularioReglaFila5.setSpacing(true);
		btnGrabarRegla = new Button();
		btnGrabarRegla.setCaption("Actualizar");
		btnGrabarRegla.setImmediate(true);
		hlyFormularioReglaFila5.addComponent(btnGrabarRegla);
		hlyFormularioReglaFila5.setComponentAlignment(btnGrabarRegla, new Alignment(20));
		btnEliminarRegla = new Button();
		btnEliminarRegla.setCaption("Eliminar");
		btnEliminarRegla.setImmediate(true);
		hlyFormularioReglaFila5.addComponent(btnEliminarRegla);
		hlyFormularioReglaFila5.setComponentAlignment(btnEliminarRegla, new Alignment(20));
		return hlyFormularioReglaFila5;
	}

	@Override
	public void handleEnterAction(TablaFiltroEnterEvent event) {
		Map<String, Object> datosBusqueda=event.getDatos();
		buscarRegla(datosBusqueda);
	}
	
	public void buscarRegla(Map<String, Object> datosBusqueda){
		Iterator<String> llaveBusqueda=datosBusqueda.keySet().iterator();
		Regla regla=new Regla();
		while(llaveBusqueda.hasNext()){
			String llave = llaveBusqueda.next();
			Object dato = datosBusqueda.get(llave);
			if(llave.equals(NOMBRE)){
				regla.setNombre(dato.toString());
			}else if(llave.equals(CODIGO)){
				regla.setCodigo(dato.toString());
			}else if(llave.equals(TIPO_REGLA)){
				Valor valorRegla=new Valor();
				valorRegla.setNombre(dato.toString());
				regla.setTipo(valorRegla);
			}else if(llave.equals(ESTADO)){
				Valor valorEstado=new Valor();
				valorEstado.setNombre(dato.toString());
				regla.setEstado(valorEstado);
			}
		}
		List<Regla> lstRegla=genericoNegocio.buscarReglas(regla);
		cargarReglas(lstRegla);
	}
}